import streamlit as st
import pywencai
import requests
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
from chinese_calendar import is_workday, is_holiday
import schedule
import time
from datetime import datetime, time as dt_time

# Setting up pandas display options
pd.set_option('display.unicode.ambiguous_as_wide', True)
pd.set_option('display.unicode.east_asian_width', True)
pd.set_option('display.max_rows', None)
pd.set_option('display.max_columns', None)
pd.set_option('display.expand_frame_repr', False)
pd.set_option('display.max_colwidth', 100)


def get_previous_trading_day(date):
    previous_date = date - timedelta(days=1)
    while not is_workday(previous_date) or is_holiday(previous_date):
        previous_date -= timedelta(days=1)
    return previous_date


def get_limit_up_data(date):
    param = f"非ST,{date.strftime('%Y%m%d')}涨停"
    df = pywencai.get(query=param, sort_key='成交金额', sort_order='desc', loop=True)
    return df

def get_czb_limit_up_data(date):
    param = f"非ST,创业板,{date.strftime('%Y%m%d')}涨停"
    df = pywencai.get(query=param, sort_key='成交金额', sort_order='desc', loop=True)
    return df

def get_yzb_limit_up_data(date):
    param = f"非ST,一字板,{date.strftime('%Y%m%d')}涨停"
    df = pywencai.get(query=param, sort_key='成交金额', sort_order='desc', loop=True)
    return df

def get_yesterday_zhangting_data(previous_date , date):
    param = f"非ST,{previous_date.strftime('%Y%m%d')}涨停"
    df = pywencai.get(query=param, sort_key='成交金额', sort_order='desc', loop=True)
    return df


def get_poban(date):
    param = f"非ST,{date.strftime('%Y%m%d')}曾涨停"
    df = pywencai.get(query=param, sort_key='成交金额', sort_order='desc', loop=True)
    return df

def get_limit_down_data(date):
    param = f"非ST,{date.strftime('%Y%m%d')}跌停"
    df = pywencai.get(query=param, sort_key='成交金额', sort_order='desc', loop=True)
    return df


def analyze_continuous_limit_up(df, date):
    # 提取连续涨停天数列和涨停原因类别列
    continuous_days_col = f'连续涨停天数[{date.strftime("%Y%m%d")}]'
    reason_col = f'涨停原因类别[{date.strftime("%Y%m%d")}]'

    # 确保涨停原因类别列存在
    if reason_col not in df.columns:
        df[reason_col] = '未知'

    # 按连续涨停天数降序排序，然后按涨停原因类别排序
    df_sorted = df.sort_values([continuous_days_col, reason_col], ascending=[False, True])

    # 创建结果DataFrame
    result = pd.DataFrame(columns=['连续涨停天数', '股票代码', '股票简称', '涨停原因类别'])

    # 遍历排序后的DataFrame，为每只股票创建一行
    for _, row in df_sorted.iterrows():
        new_row = pd.DataFrame({
            '连续涨停天数': [row[continuous_days_col]],
            '股票代码': [row['股票代码']],
            '股票简称': [row['股票简称']],
            '涨停原因类别': [row[reason_col]]
        })
        result = pd.concat([result, new_row], ignore_index=True)

    return result


def get_concept_counts(df, date):
    concepts = df[f'涨停原因类别[{date.strftime("%Y%m%d")}]'].str.split('+').explode().reset_index(drop=True)
    #concepts = df[f'涨停原因类别[{date.strftime("%Y%m%d")}]'].str.split('+', n=1).str[0].reset_index(drop=True)
    concept_counts = concepts.value_counts().reset_index()
    concept_counts.columns = ['概念', '出现次数']
    return concept_counts


def calculate_promotion_rates(current_df, previous_df, current_date, previous_date):
    """Calculate promotion rates between consecutive days"""
    current_days_col = f'连续涨停天数[{current_date.strftime("%Y%m%d")}]'
    previous_days_col = f'连续涨停天数[{previous_date.strftime("%Y%m%d")}]'

    promotion_data = []

    # Calculate for each level (from 1 to max consecutive days)
    max_days = max(current_df[current_days_col].max(), previous_df[previous_days_col].max())
    for days in range(1, int(max_days)):
        # Previous day count for current level
        prev_count = len(previous_df[previous_df[previous_days_col] == days])
        # Current day count for next level
        curr_count = len(current_df[current_df[current_days_col] == days + 1])

        if prev_count > 0:
            promotion_rate = f"{curr_count}/{prev_count}={round(curr_count / prev_count * 100 if prev_count > 0 else 0)}%"
        else:
            promotion_rate = "N/A"

        # Get stocks that promoted
        promoted_stocks = current_df[current_df[current_days_col] == days + 1][
            ['股票简称', f'涨停原因类别[{current_date.strftime("%Y%m%d")}]']]

        promotion_data.append({
            '连板数': f"{days}板{days + 1}",
            '晋级率': promotion_rate,
            '股票列表': promoted_stocks
        })

    return pd.DataFrame(promotion_data)

def getAndSendReportNew():
    # Date selection
    max_date = datetime.now().date()
    selected_date = max_date
    
    if not is_workday(selected_date) or is_holiday(selected_date):
        selected_date = get_previous_trading_day(selected_date)

    # 获取关键数据
    selected_df = get_limit_up_data(selected_date)  # 今日涨停
    selected_cyb_df = get_czb_limit_up_data(selected_date)  # 今日创业板涨停
    selected_yzb_df = get_yzb_limit_up_data(selected_date)  # 今日一字板涨停

    # Analyze continuous limit-up for both days
    selected_continuous = analyze_continuous_limit_up(selected_df, selected_date)
    selected_cyb_continuous = analyze_continuous_limit_up(selected_cyb_df, selected_date)
    selected_yzb_continuous = analyze_continuous_limit_up(selected_yzb_df, selected_date)
    
    # 筛选连续涨停天数 ≥ 2 的股票
    two_plus_boards = selected_continuous[selected_continuous['连续涨停天数'] >= 2]
    
    # 打印日志
    print("交易日日期:", selected_date)
    print("创业板及以上股票：", selected_cyb_continuous)
    print("一字板的股票：", selected_yzb_continuous)
    print("2板及以上股票：", two_plus_boards)
    
    # 准备发送的数据（包含创业板、一字板和2板以上）
    stocks_data = {
        '创业板股票': selected_cyb_continuous.to_dict(orient='records'),
        '一字板股票': selected_yzb_continuous.to_dict(orient='records'),
        '两板及以上股票': two_plus_boards.to_dict(orient='records'),
        'selected_date': selected_date.strftime('%Y-%m-%d')  # 添加日期信息
    }
    
    print("整合后的股票数据:", stocks_data)
    
    # 请求参数
    payload = {
        'data': stocks_data,  # 使用整合后的数据
        'receiver': 'XXX@163.com',  # 实际收件人邮箱
        'subject': f'ztgp报告（{selected_date.strftime("%Y-%m-%d")}）'  # 邮件标题带日期
    }
    
    try:
        # 发送请求到Flask服务
        response = requests.post(
            'http://localhost:5000/api/send_multi_data',
            json=payload,
            headers={'Content-Type': 'application/json'},
            timeout=10
        )

        # 处理响应
        print(f"发送时间:{datetime.now().time()}")
        if response.status_code == 200:
            result = response.json()
            print(f"成功: {result['message']}")
        else:
            print(f"失败: {response.status_code} - {response.text}")
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {str(e)}")

def getAndSendReport():
    # Date selection
    max_date = datetime.now().date()
    selected_date = max_date

    previous_date = get_previous_trading_day(selected_date)

    # 获取关键数据
    selected_df = get_limit_up_data(selected_date)  # 今日涨停
    previous_df = get_limit_up_data(previous_date)  # 昨日涨停

    # Analyze continuous limit-up for both days
    selected_continuous = analyze_continuous_limit_up(selected_df, selected_date)
    
    # 筛选连续涨停天数 ≥ 2 的股票
    two_plus_boards = selected_continuous[selected_continuous['连续涨停天数'] >= 2]
    
    print("2板及以上股票：")
    print(two_plus_boards)
    
    # 将DataFrame转换为可序列化的字典列表
    stocks_data = two_plus_boards.to_dict(orient='records')
    
    # 请求参数
    payload = {
        'data': stocks_data,  # 使用转换后的数据
        'receiver': 'XXX@163.com',  # 实际收件人邮箱
        'subject': '2板及以上股票报告'
    }
    
    try:
        # 发送请求到Flask服务
        response = requests.post(
            'http://localhost:5000/api/send_data',
            json=payload,
            headers={'Content-Type': 'application/json'},
            timeout=10  # 添加超时设置
        )

        # 处理响应
        print(f"发送时间:{datetime.now().time()}")
        if response.status_code == 200:
            result = response.json()
            print(f"成功: {result['message']}")
        else:
            print(f"失败: {response.status_code} - {response.text}")
    except requests.exceptions.RequestException as e:
        print(f"请求失败: {str(e)}")

def should_send_report():
    now = datetime.now()
    # 检查是否是工作日（周一=0，周五=4）
    if now.weekday() in [0, 4] and is_workday(now) and not is_holiday(now):
        # 检查当前时间是否是11:31或15:01
        current_time = now.time()
        return (current_time >= dt_time(11, 31) and current_time <= dt_time(11, 32)) or \
               (current_time >= dt_time(15, 1) and current_time <= dt_time(15, 2))
    return False

def scheduled_report():
    if should_send_report():
        getAndSendReport()  # 调用你的原有报告函数

if __name__ == "__main__":
    print("start time:", datetime.now())
    # 使用 cron 风格的定时任务（每天 11:29 和 14:59）
    schedule.every().day.at("09:26").do(getAndSendReportNew)
    schedule.every().day.at("10:01").do(getAndSendReportNew)
    schedule.every().day.at("11:29").do(getAndSendReportNew)
    schedule.every().day.at("14:00").do(getAndSendReportNew)
    schedule.every().day.at("14:59").do(getAndSendReportNew)
    
    # 保持程序运行
    while True:
        schedule.run_pending()
        time.sleep(1)
